package com.tiancheng.trade.order.mq;

import com.tiancheng.trade.commom.core.data.MessageBody;
import com.tiancheng.trade.commom.core.enums.MessageTypeEnum;
import com.tiancheng.trade.commom.core.exception.Asserts;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.commom.core.utils.MessageUtils;
import com.tiancheng.trade.order.bo.cmq.*;
import com.tiancheng.trade.order.bo.notify.PayResultOrderBO;
import com.tiancheng.trade.order.bo.ums.QrcOrderCacheBO;
import com.tiancheng.trade.order.configuration.CallbackConfig;
import com.tiancheng.trade.order.enums.CreditOrderMsgTagEnum;
import com.tiancheng.trade.order.mq.producer.OrderStatus2OrderMsgProducer;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * cmq消息推送
 *
 * @author kellen
 * @date 2024/3/26
 */
@Slf4j
@Component
public class MessageProducer {

    @Resource
    private OrderStatus2OrderMsgProducer orderStatus2OrderMsgProducer;
    @Resource
    private CallbackConfig callbackConfig;
    /**
     * 退款
     *
     * @param refundMsgBO
     */
    public boolean refund(RefundMsgBO refundMsgBO) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_refund.getCode(), refundMsgBO,refundMsgBO.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);

            log.info("推送退款消息message:{}", msgBodyStr);
            sendCallbackMessage(msgBody, MessageTypeEnum.order_refund,1000);
            return true;
        } catch (Exception e) {
            log.error("cmq推送退款消息失败:{}, {}", JsonUtil.toJsonString(refundMsgBO), e.getMessage(), e);
            return false;
        }
    }


    /**
     * 核销、释放优惠券消息
     *
     * @param couponMsgBO
     */
    public boolean coupon(CouponMsgBO couponMsgBO) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_coupon.getCode(), couponMsgBO,couponMsgBO.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);

            log.info("推送优惠券消息message:{}", msgBodyStr);
            sendCallbackMessage(msgBody, MessageTypeEnum.order_coupon,1000);
            log.info("推送优惠券消息完成");
            return true;
        } catch (Exception e) {
            log.error("cmq推送优惠券消息失败:{}, {}", JsonUtil.toJsonString(couponMsgBO), e.getMessage(), e);
            return false;
        }
    }

    /**
     * 订单支付结果，通知业务侧
     *
     * @param payResultMsgBO
     */
    public boolean payResult(PayResultOrderBO payResultMsgBO) {
        try {
            // 根据order 的system_source判断，如果不为空&&不是youyunnna，则加上tag加上前缀
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_pay_result.getCode(), payResultMsgBO,payResultMsgBO.getClientId());


            String msgBodyStr = JsonUtil.toJsonString(msgBody);
            log.info("推送支付结果消息pay_success,message:{}", msgBodyStr);
            sendCallbackMessage(msgBody, MessageTypeEnum.order_pay_result,100);
            log.info("推送支付结果消息完成！");
            return true;
        } catch (Exception e) {
            log.error("cmq推送订单支付结果，通知业务侧失败:{}, {}", JsonUtil.toJsonString(payResultMsgBO), e.getMessage(), e);
            return false;
        }
    }

    /**
     * 订单退款结果，通知业务侧
     *
     * @param refundResultMsgBO
     * @return
     */
    public boolean refundResult(RefundResultMsgBO refundResultMsgBO) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_refund_result.getCode(), refundResultMsgBO,refundResultMsgBO.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);
            log.info("推送退款结果消息message:{}", msgBodyStr);
            sendCallbackMessage(msgBody, MessageTypeEnum.order_refund_result,100);
            log.info("推送退款结果消息完成！");
            return true;
        } catch (Exception e) {
            log.error("cmq推送订单退款结果，通知业务侧失败:{}, {}", JsonUtil.toJsonString(refundResultMsgBO), e.getMessage(), e);
            return false;
        }
    }

    /**
     * apple订单退款结果，通知业务侧
     *
     * @param appleRefundResultMsgBO
     * @return
     */
    public boolean appleRefundResult(AppleRefundResultMsgBO appleRefundResultMsgBO) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_refund_result.getCode(), appleRefundResultMsgBO,appleRefundResultMsgBO.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);

            log.info("推送apple退款结果消息message:{}", msgBodyStr);
            sendCallbackMessage(msgBody, MessageTypeEnum.order_refund_result,100);
            log.info("推送apple退款结果消息完成！");
            return true;
        } catch (Exception e) {
            log.error("cmq推送apple订单退款结果，通知业务侧失败:{}, {}", JsonUtil.toJsonString(appleRefundResultMsgBO), e.getMessage(), e);
            return false;
        }
    }

    private void initRoutingKey(MessageBody messageBody, String clientId){
        Optional<CallbackConfig.BizConfig> bizConfig = callbackConfig.getConfigs().stream().filter(c -> c.getClientId().equals(clientId)).findFirst();
        Asserts.isTrue(bizConfig.isPresent(),"未读取到队列配置！");
        messageBody.setRoutingKey(bizConfig.get().getRoutingKey());
    }

    /**
     * 组织生成消息内容
     *
     * @param data
     * @return
     */
    private MessageBody getMsgData(String messageType, Object data,String clientId) {
        MessageBody msgData = MessageUtils.getMsgData(messageType, data);
        initRoutingKey(msgData,clientId);
        return MessageUtils.sign(msgData,callbackConfig.getSignKey()) ;
    }


    /**
     * 推送芝麻信用预授权订单信息到业务侧：1、预授权订单完结、2、预授权订单完结 3、预授权订单取消
     *
     * @param creditOrderBO
     * @param creditOrderMsgTagEnum
     * @return
     */
    public boolean tallyBizCreditOrder(CreditOrderBO creditOrderBO, CreditOrderMsgTagEnum creditOrderMsgTagEnum) {
        try {
            /*MessageBody msgBody = this.getMsgData(creditOrderMsgTagEnum.getCode(), creditOrderBO);
            String msgBodyStr = JsonUtil.toJsonString(msgBody);
            // tag为租车
            String tag = bizTags.get(OrderSourceEnum.TRAFFIC.getCode());
            log.info("推送芝麻信用预授权订单tag:{},message:{}", tag, msgBodyStr);
            final SendResult s = messageTemplate.send(tradeTopic, tag, msgBody);

            log.info("推送芝麻信用预授权订单messageId:{}", s);*/
            return true;
        } catch (Exception e) {
            log.error("cmq推送失败:{}, {}", JsonUtil.toJsonString(creditOrderBO), e.getMessage(), e);
            return false;
        }
    }


    /**
     * 延时关闭二维码订单
     *
     * @param qrcOrderCacheBO 消息体
     * @param delaySeconds    延迟时间
     * @return
     */
    public boolean qrOrderCloseMessage(QrcOrderCacheBO qrcOrderCacheBO, int delaySeconds) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.qrc_close.getCode(), qrcOrderCacheBO,qrcOrderCacheBO.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);

			/*log.info("cmq设置延时关闭二维码订单消息，cmdStr:{},message:{}", msgBody.getCmdStr(), msgBodyStr);
			final QueueProducer queueProducer = cmqProducer.getQueue(midQueue);
			queueProducer.sendMessage(msgBodyStr,delaySeconds);*/
            return true;
        } catch (Exception e) {
            log.error("cmq设置延时关闭二维码订单消息失败:{}, {}", JsonUtil.toJsonString(qrcOrderCacheBO), e.getMessage(), e);
            return false;
        }
    }

    /**
     * 订单转状态消息添加到消息队列
     *
     * @param orderStateChangeMsgBo 消息体
     * @return
     */
    public boolean orderStateChangeMessage(OrderStateChangeMsgBo orderStateChangeMsgBo) {
        try {
            MessageBody msgBody = this.getMsgData(MessageTypeEnum.order_sub_status_change.getCode(), orderStateChangeMsgBo,orderStateChangeMsgBo.getClientId());
            String msgBodyStr = JsonUtil.toJsonString(msgBody);

//			final QueueProducer queueProducer = cmqProducer.getQueue(orderStateQueue);
//			queueProducer.sendMessage(msgBodyStr);
            return true;
        } catch (Exception e) {
            log.error("cmq订单转状态消息失败:{}, {}", JsonUtil.toJsonString(orderStateChangeMsgBo), e.getMessage(), e);
            return false;
        }
    }


    /**
     * 发送回调消息
     *
     * @param msgBody
     */
    private void sendCallbackMessage(MessageBody msgBody, MessageTypeEnum messageTypeEnum, long expiration) {
        switch (messageTypeEnum) {
            case order_pay_result:
            case order_refund_result:
                // 推送订单支付消息到订单中心
                orderStatus2OrderMsgProducer.sendMessage(msgBody, 500);
                log.info("订单支付消息到订单中心完成");
                break;
            case order_refund:
                break;
            case order_coupon:
                break;
            case qrc_trade:
                break;
        }
    }


}
